import json
import random
import re
from datetime import datetime

from flask import request, current_app, make_response, jsonify, session
from . import passport_blue
from ... import redis_store, constants, db
from ...libs.yuntongxun.sms import CCP
from ...models import User
from ...utils.captcha.captcha import captcha
# 功能：获取验证码
# 请求路径：/passport/image_code/
# 携带参数cur_id,pre_id
# 返回值：图片
from ...utils.response_code import RET


@passport_blue.route('/image_code/')
def get_code():
    # 1.获取前端传递的cur_id
    cur_id = request.args.get('cur_id')
    # 2.验证码编号，验证码值，验证码图片
    name, text, image_data = captcha.generate_captcha()
    # 3.将图片验证码保存到redis中 所有数据库的增删改查都要捕获异常
    try:
        redis_store.set('image_code:%s' % cur_id, text, constants.IMAGE_CODE_REDIS_EXPIRES)
        # 4.判断是否有上次的验证码，如果有就删除，减小redis数据库压力
        pre_id = request.args.get('pre_id')
        if pre_id:
            redis_store.delete('image_code:%s' % pre_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="图片验证码操作失败")
    response = make_response(image_data)
    response.headers['Content-Type'] = 'image/png'
    return response


# 功能：获取短信验证码
# 请求路径: /passport/sms_code
# 请求方式: POST
# 请求参数: mobile, image_code,image_code_id
# 返回值: errno, errmsg
@passport_blue.route('/sms_code', methods=['POST'])
def sms_code():
    # 1. 获取参数 前端发送的是ajax请求，是json字符串
    json_data = request.data
    dict_data = json.loads(json_data)
    mobile = dict_data.get('mobile').strip() if dict_data.get('mobile') else None
    image_code = dict_data.get('image_code').strip() if dict_data.get('image_code') else None
    image_code_id = dict_data.get('image_code_id')
    # 2. 参数的为空校验
    if not all([mobile, image_code, image_code_id]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不全')
    # 3. 校验手机的格式
    if not re.match(r'1[356789]\d{9}', mobile):
        return jsonify(errno=RET.DATAERR, errmsg="手机号码格式错误")
    # 4. 通过图片验证码编号获取,图片验证码
    try:
        redis_image_code = redis_store.get('image_code:%s' % image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="操作redis失败")
    # 5. 判断图片验证码是否过期
    if not redis_image_code:
        return jsonify(errno=RET.NODATA, errmsg='验证码过期')
    # 6. 判断图片验证码是否正确
    if redis_image_code.lower() != image_code:
        return jsonify(errno=RET.DATAERR, errmsg="验证码错误")
    # 7. 删除redis中的图片验证码
    try:
        redis_store.delete('image_code:%s' % image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="删除redis验证码失败")

    # 8. 生成一个随机的短信验证码, 调用ccp发送短信,判断是否发送成功
    sms_code = '%06d' % random.randint(0, 999999)
    # ccp = CCP()
    # result = ccp.send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], 1)
    # if result == -1:
    #     return jsonify(errno=RET.DATAERR, errmsg="短信发送失败")
    # 9. 将短信验证码保存到redis中 手机号作为key
    print('验证码：%s' % sms_code)
    try:
        redis_store.set('sms_code:%s' % mobile, sms_code, constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="保存验证码失败")
    # 10. 返回响应
    return jsonify(errno=RET.OK, errmsg="短信发送成功")


# 请求路径: /passport/register
# 请求方式: POST
# 请求参数: mobile, sms_code,password
# 返回值: errno, errmsg
@passport_blue.route('/register', methods=['POST'])
def register():
    # 1.获取参数  前台为ajax请求，传递json字符串 （手机号，手机验证码，密码）
    json_data = request.data
    dict_data = json.loads(json_data)

    mobile = dict_data.get('mobile').strip() if dict_data.get('mobile') else None
    sms_code = dict_data.get('sms_code').strip() if dict_data.get('sms_code') else None
    password = dict_data.get('password').strip() if dict_data.get('password') else None
    # 2.非空校验
    if not all([mobile, sms_code, password]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    # 3.手机号再次校验
    if not re.match(r'^1[3456789]\d{9}$', mobile):
        return jsonify(errno=RET.DATAERR, errmsg="手机号码格式错误")
    # 从数据库查询，如果有该手机号，说明已经注册
    try:
        user = User.query.filter(User.mobile == mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库错误")
    if user:
        return jsonify(errno=RET.DATAEXIST, errmsg="该用户已存在")
    # 4.从redis中取出保存的手机验证码（以sms_code:mobile为键的形式保存）
    try:
        redis_sms_code = redis_store.get('sms_code:%s' % mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库错误")
    # 5.判断手机验证码是否过期
    if not redis_sms_code:
        return jsonify(errno=RET.NODATA, errmsg="验证码过期")
    # 6.判断验证码是否一致
    if redis_sms_code != sms_code:
        return jsonify(errno=RET.DATAERR, errmsg="短信验证码错误")
    # 7，删除redis中短信验证码
    try:
        redis_store.delete('sms_code:%s' % mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="短信验证码删除失败")
    # 8.创建用户对象
    user = User()

    # 9.设置用户属性
    user.nick_name = mobile
    # 其实调用的settpassword方法
    user.password = password
    user.mobile = mobile
    db.session.add(user)
    # 10.保存在数据库中
    # try:
    #     db.session.add(user)
    #     db.session.commit()
    # except Exception as e:
    #     current_app.logger.error(e)
    #     return jsonify(errno=RET.DBERR, errmsg="用户注册失败")
    # 11.返回响应
    return jsonify(errno=RET.OK, errmsg="注册成功")

# 请求路径: /passport/login
# 请求方式: POST
# 请求参数: mobile,password
# 返回值: errno, errmsg
@passport_blue.route('/login', methods=['POST'])
def login():
    # 1.获取参数（手机号，密码）
    dict_data = request.json
    mobile = dict_data.get('mobile')
    password = dict_data.get('password')
    # 2.校验参数
    if not all([mobile, password]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    # 3.通过手机号，到数据库查询用户判断是否存在该用户
    try:
        user = User.query.filter(User.mobile == mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库错误")
    if not user:
        return jsonify(errno=RET.DATAERR, errmsg="查询不到该用户")
    # 4.验证密码
    if not user.check_passowrd(password):
        return jsonify(errno=RET.DATAERR, errmsg="密码错误")
    # 5.将用户登录信息保存session中
    session['user_id'] = user.id
    #.更新用户最后登录时间，为了最后用户活跃信息的统计
    user.last_login = datetime.now()
    #.提交
    # try:
    #     db.session.add(user)
    #     db.session.commit()
    # except Exception as e:
    #     current_app.logger.error(e)
    #已经在config中配置过了，会自动提交
    # 6.返回响应
    return jsonify(errno=RET.OK, errmsg="登录成功")


# 登出接口
# 请求路径: /passport/logout
# 请求方式: POST
# 请求参数: 无
# 返回值: errno, errmsg
@passport_blue.route('/logout', methods=['POST'])
def logout():
    # 清除session 没有就为None
    session.pop('user_id', None)
    session.pop('is_admin',None)
    return jsonify(errno=RET.OK, errmsg="登出成功")
